package com.party.admin.web.controller.system;

import com.alibaba.fastjson.JSONArray;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.party.admin.biz.system.RoleBizService;
import com.party.admin.web.dto.AjaxResult;
import com.party.common.paging.Page;
import com.party.common.utils.LangUtils;
import com.party.core.model.BaseModel;
import com.party.core.model.YesNoStatus;
import com.party.core.model.member.Member;
import com.party.core.model.system.*;
import com.party.core.service.member.IMemberService;
import com.party.core.service.system.IMemberSysRoleService;
import com.party.core.service.system.ISysPrivilegeService;
import com.party.core.service.system.ISysRolePrivilegeService;
import com.party.core.service.system.ISysRoleService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import java.util.*;

/**
 * 角色控制器
 *
 * @author Administrator
 *
 */
@Controller
@RequestMapping(value = "/system/role")
public class SysRoleController {

	@Autowired
	private ISysRoleService sysRoleService;

	@Autowired
	private ISysPrivilegeService sysPrivilegeService;

	@Autowired
	private IMemberService memberService;

	@Autowired
	private IMemberSysRoleService memberSysRoleService;

	@Autowired
	private ISysRolePrivilegeService sysRolePrivilegeService;

	@Autowired
    private RoleBizService roleBizService;

	Logger logger = LoggerFactory.getLogger(getClass());

	/**
	 * 跳转至列表
	 *
	 * @return
	 */
	@RequestMapping(value = "roleList")
	public ModelAndView publishList(SysRole sysRole, Page page) {
		ModelAndView mv = new ModelAndView("system/role/roleList");
		page.setLimit(20);
		sysRole.setDelFlag("0");
		if(null == sysRole.getType()){
		    sysRole.setType(0);
        }
		sysRole.setDelFlag(BaseModel.DEL_FLAG_NORMAL);
		List<SysRole> sysRoles = sysRoleService.listPage(sysRole, page);
		Map<Integer, String> types = RoleType.convertMap();
		mv.addObject("types", types);
		mv.addObject("sysRoles", sysRoles);
		mv.addObject("page", page);
		return mv;
	}

	/**
	 * 跳转至 分配权限
	 *
	 * @param roleId
	 * @return
	 */
	@RequestMapping(value = "roleAuth")
	public ModelAndView roleAuth(String roleId) {
		ModelAndView mv = new ModelAndView("system/role/roleAuth");

		// 权限列表
		SysPrivilege privilege = new SysPrivilege();
		privilege.setDelFlag(BaseModel.DEL_FLAG_NORMAL);
		List<SysPrivilege> privileges = sysPrivilegeService.list(privilege);
		mv.addObject("privileges", privileges);

		Set<SysPrivilege> sysPrivileges = new HashSet<SysPrivilege>(sysPrivilegeService.findByRoleId(roleId));
		mv.addObject("myPrivileges", sysPrivileges);
		mv.addObject("roleId", roleId);
		return mv;
	}

	/**
	 * 跳转至 分配角色
	 *
	 * @param
	 * @return
	 */
	@RequestMapping(value = "distributionRole")
	public ModelAndView distributionRole(String memberId, String identity, Integer type,
										 String partnerId, Boolean isNew, Integer typeId) {
		ModelAndView mv = new ModelAndView("system/role/distributionRole");

		// 用户已有的角色
		List<SysRole> myRoles = sysRoleService.findByMemberId(memberId);
		List<String> myRoleIds = LangUtils.transform(myRoles, input -> input.getId());
		mv.addObject("myRoleIds", myRoleIds);
		mv.addObject("myRoleIdsJson", JSONArray.toJSONString(myRoleIds));

		if (StringUtils.isEmpty(partnerId)) {
			Map<String, List<SysRole>> systemMap = roleBizService.toAssignRole(identity, type);
			mv.addObject("sysRoles", systemMap);
		} else if (null != typeId) {
			if (new Integer(1).equals(typeId)) {   //一级子账号查父级已有的角色
				// 父级已有的角色
				Map<String, List<SysRole>> partnerRoleMap = Maps.newHashMap();
				if (StringUtils.isNotEmpty(partnerId)) {
					List<SysRole> partnerRoles = sysRoleService.findByMemberId(partnerId);
					for (SysRole myRole : partnerRoles) {
						if (RoleType.SYSTEM_ROLE.getCode().equals(myRole.getType())) {
							continue;
						}
						String roleTypeName = RoleType.getValue(myRole.getType());
						List<SysRole> sysRoles = partnerRoleMap.get(roleTypeName);
						if (null == sysRoles) {
							sysRoles = Lists.newArrayList();
						}
						if (sysRoles.size() == 0) {
							sysRoles.add(myRole);
						} else {
							boolean contains = sysRoles.contains(myRole);
							if (!contains) {
								sysRoles.add(myRole);
							}
						}

						partnerRoleMap.put(roleTypeName, sysRoles);
					}

//					SysRole partnerRole = sysRoleService.getRole(RoleEnum.PARTNER_ROLE.getCode(), RoleType.SYSTEM_ROLE.getCode());
//					SysRole cosponsorRole = sysRoleService.getRole(RoleEnum.COSPONSOR_ROLE.getCode(), RoleType.SYSTEM_ROLE.getCode());
//					List<SysRole> sysRoles = Lists.newArrayList();
//					sysRoles.add(partnerRole);
//					sysRoles.add(cosponsorRole);
//					partnerRoleMap.put(RoleType.SYSTEM_ROLE.getValue(), sysRoles);
				}

				mv.addObject("sysRoles", partnerRoleMap);
			} else if (new Integer(2).equals(typeId)) {  //二级查行知公社管理角色
				SysRole sysRole = new SysRole();
				sysRole.setType(RoleType.KNOWLEDGE_MANAGEMENT_ROLE.getCode());
				sysRole.setDelFlag(BaseModel.DEL_FLAG_NORMAL);
				List<SysRole> sysRoles = sysRoleService.list(sysRole);
				HashMap<String, List<SysRole>> mapSysRoles = Maps.newHashMap();
				mapSysRoles.put(RoleType.KNOWLEDGE_MANAGEMENT_ROLE.getValue(),sysRoles);
				mv.addObject("sysRoles",mapSysRoles);
			}
		}
		mv.addObject("memberId", memberId);
		mv.addObject("isNew", isNew);
		return mv;
	}

    /**
     * 保存分配角色
     *
     * @param memberId
     * @param roleIds
     * @return
     */
    @ResponseBody
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @RequestMapping(value = "saveDistributionRole")
    public AjaxResult saveDistributionRole(String memberId, String roleIds, Boolean isNew) {
        try {
        	if (null == isNew) {
        		isNew = false;
			}
			if (isNew) {
				roleBizService.assignRoleMemberGroup(roleIds, memberId);
			} else {
				roleBizService.assignRole(roleIds, memberId);
			}
			return AjaxResult.success();
        } catch (Exception e) {
            logger.error("保存分配角色异常", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("保存失败");
        }
    }

	/**
	 * 保存 角色分配权限
	 *
	 * @param roleId
	 * @param privilegeIds
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "saveRoleAuth")
	public AjaxResult saveAuth(String roleId, String privilegeIds) {
		try {
			if (StringUtils.isNotEmpty(privilegeIds)) {
				sysRolePrivilegeService.deleteByRoleId(roleId);
				for (String privilegeId : privilegeIds.split(",")) {
					SysRolePrivilege sysRolePrivilege = new SysRolePrivilege(roleId, privilegeId);
					sysRolePrivilegeService.insert(sysRolePrivilege);
				}
			} else {
				sysRolePrivilegeService.deleteByRoleId(roleId);
			}
		} catch (Exception e) {
			e.printStackTrace();
			return new AjaxResult(false, "error");
		}
		return new AjaxResult(true, "success");
	}


	/**
	 * 查看角色
	 * @param id 角色编号
	 * @return 交互数据
	 */
	@RequestMapping(value = "view")
	public ModelAndView view(String id){
		ModelAndView modelAndView = new ModelAndView("system/role/roleView");
		SysRole sysRole;
		if (Strings.isNullOrEmpty(id)){
			sysRole = new SysRole();
		}
		else {
			sysRole = sysRoleService.get(id);
		}

		Map<Integer, String> types = RoleType.convertMap();
		modelAndView.addObject("types", types);
		modelAndView.addObject("role", sysRole);
		return modelAndView;
	}

	/**
	 * 保存角色
	 * @param sysRole 角色
	 * @return 交互数据
	 */
	@ResponseBody
	@RequestMapping(value = "save")
	public AjaxResult save(SysRole sysRole){
		AjaxResult ajaxResult = new AjaxResult();
		if (Strings.isNullOrEmpty(sysRole.getId())){
			sysRoleService.insert(sysRole);
		}
		else {
			sysRoleService.update(sysRole);
		}
		ajaxResult.setSuccess(true);
		return ajaxResult;
	}

	/**
	 * 删除角色
	 * @param id
	 * @return
	 */
	@ResponseBody
	@RequestMapping("delete")
	public AjaxResult delete(String id) {
		if (StringUtils.isEmpty(id)) {
			return AjaxResult.error("主键不能为空");
		}
		List<MemberSysRole> memberSysRoles = memberSysRoleService.findByRoleId(id);
		if (memberSysRoles.size() > 0) {
			return AjaxResult.error("11");
		} else {
			sysRoleService.delete(id);
			return AjaxResult.success();
		}
	}

	/**
	 * 检查编码
	 * @param code
	 * @param id
	 * @return
	 */
	@ResponseBody
	@RequestMapping("checkCode")
	public boolean checkCode(String code, String id) {
		if(StringUtils.isEmpty(code)) {
			return false;
		}
		List<SysRole> roles = sysRoleService.checkCode(code, id);
		if (roles.size() > 0) {
			return false;
		}
		return true;
	}

    /**
     * 更新合作商
     *
     * @return
     */
    @ResponseBody
    @RequestMapping("updatePartner")
    public AjaxResult updatePartner() {
        // 已经有合作商角色但是is_partner不是1的用户
        Map<String, Object> params = Maps.newHashMap();
        params.put("isPartner", YesNoStatus.YES.getCode());
        List<String> memberIds = sysRoleService.getErrorData(params);
        for (String memberId : memberIds) {
            Member member = memberService.get(memberId);
            member.setIsPartner(YesNoStatus.YES.getCode());
            member.setUpdateDate(null);
            memberService.update(member);
        }

        Integer count = 0;
        Member mm = new Member();
        mm.setIsPartner(YesNoStatus.YES.getCode());
        List<Member> partnerList = memberService.list(mm);
        for (Member m : partnerList) {
            // 没有合作商就补充
            boolean partnerResult = sysRoleService.hasRole(m.getId(), RoleEnum.PARTNER_ROLE.getCode());
            if (partnerResult == false) {
                SysRole partnerRole = sysRoleService.uniqueProperty(new SysRole("", RoleEnum.PARTNER_ROLE.getCode()));
                MemberSysRole memberSysRole = new MemberSysRole(m.getId(), partnerRole.getId());
                memberSysRoleService.insert(memberSysRole);
                count++;
            }
            List<SysRole> roles = sysRoleService.findByMemberId(m.getId());
            for (SysRole role : roles) {
                // 不能是管理员，不能是平台角色，不能是达人
                if (role.getType().equals(RoleType.PLATFORM_ROLE.getCode()) || role.getCode().equals(RoleEnum.ADMIN_ROLE.getCode())
                        || role.getCode().equals(RoleEnum.EXPERT_ROLE.getCode())) {
                    memberSysRoleService.deleteByRoleIdAndMemberId(role.getId(), m.getId());
                }
            }
        }
        Map<String, Object> returnResult = Maps.newHashMap();
        returnResult.put("errorData", memberIds.size());
        returnResult.put("updateData", count);
        return AjaxResult.success(returnResult);
    }

	/**
	 * 更新有达人字段但是没有达人角色的
	 */
	@ResponseBody
	@RequestMapping("updateExpert")
	public void updateExpert() {
		List<String> notHasExpert = sysRoleService.getNotHasExpert();
		for (String memberId : notHasExpert) {
			SysRole expertRole = sysRoleService.uniqueProperty(new SysRole("", RoleEnum.EXPERT_ROLE.getCode()));
			MemberSysRole memberSysRole = new MemberSysRole(memberId, expertRole.getId());
			memberSysRoleService.insert(memberSysRole);
		}
	}

	/**
	 * 初始化ceo户外联盟机构用户为渠道分销商角色
	 *
	 * @return
	 */
	@ResponseBody
	@RequestMapping("initChannelDistributor")
	public AjaxResult initChannelDistributor() {
		SysRole channelRole = sysRoleService.uniqueProperty(new SysRole(RoleEnum.CHANNEL_DISTRIBUTOR_ROLE.getCode()));

		Member member = new Member();
		member.setIsCopartner(1);
		member.setType(2);
		List<Member> members = memberService.list(member);
		for (Member mm : members) {
			try {
				mm.setIsCopartner(2);
				memberService.update(mm);

				List<SysRole> sysRoles = sysRoleService.findByMemberId(mm.getId());
				for (SysRole sysRole : sysRoles) {
					if (RoleEnum.COPARTNER_ROLE.getCode().equals(sysRole.getCode())) {
						memberSysRoleService.deleteByRoleIdAndMemberId(sysRole.getId(), mm.getId());

						memberSysRoleService.deleteByRoleIdAndMemberId(channelRole.getId(), mm.getId());

						MemberSysRole memberSysRole = new MemberSysRole(mm.getId(), channelRole.getId());
						memberSysRoleService.insert(memberSysRole);

						break;
					}
				}
			} catch (Exception e) {
				continue;
			}
		}
		return AjaxResult.success();
	}
}
